package com.yunquan.ohana.view

import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.RectF
import android.util.AttributeSet
import android.view.View
import androidx.core.content.res.ResourcesCompat
import com.yunquan.ohana.R
import com.yunquan.ohana.utils.Utils

class LinearProgressBar @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    // 1. 自定义属性变量（默认值+布局传入值）
    private var progressBgColor: Int =
        ResourcesCompat.getColor(resources, android.R.color.darker_gray, null)
    private var progressColor: Int =
        ResourcesCompat.getColor(resources, android.R.color.holo_orange_light, null)
    private var progressRadius = Utils.instance.dp2px(8f).toFloat() // 圆角半径（dp转px）
    private var progressHeight = Utils.instance.dp2px(16f).toFloat() // 进度条高度（dp转px）
    private var maxProgress: Int = 100
    private var currentProgress: Int = 0

    // 2. 绘制工具
    private val bgPaint = Paint(Paint.ANTI_ALIAS_FLAG) // 背景画笔（抗锯齿）
    private val progressPaint = Paint(Paint.ANTI_ALIAS_FLAG) // 进度画笔（抗锯齿）
    private val bgRect = RectF() // 背景矩形区域
    private val progressRect = RectF() // 进度矩形区域

    init {
        // 加载布局中的自定义属性
        loadAttributes(attrs)
        // 初始化画笔样式
        initPaints()
    }

    /**
     * 加载布局中的自定义属性（从attrs.xml读取）
     */
    private fun loadAttributes(attrs: AttributeSet?) {
        val typedArray = context.obtainStyledAttributes(attrs, R.styleable.LinearProgressBar)
        try {
            progressBgColor =
                typedArray.getColor(R.styleable.LinearProgressBar_progressBgColor, progressBgColor)
            progressColor =
                typedArray.getColor(R.styleable.LinearProgressBar_progressBarColor, progressColor)
            progressRadius = typedArray.getDimension(
                R.styleable.LinearProgressBar_progressRadius,
                progressRadius
            )
            progressHeight = typedArray.getDimension(
                R.styleable.LinearProgressBar_progressHeight,
                progressHeight
            )
            maxProgress = typedArray.getInt(R.styleable.LinearProgressBar_maximumProgress, maxProgress)
            currentProgress =
                typedArray.getInt(R.styleable.LinearProgressBar_currentProgress, currentProgress)
        } finally {
            typedArray.recycle() // 释放资源（必须）
        }
    }

    /**
     * 初始化画笔（设置颜色、填充样式）
     */
    private fun initPaints() {
        bgPaint.apply {
            color = progressBgColor
            style = Paint.Style.FILL // 填充背景
        }
        progressPaint.apply {
            color = progressColor
            style = Paint.Style.FILL // 填充进度
        }
    }

    /**
     * 测量View尺寸（处理wrap_content/ match_parent）
     */
    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        // 宽度：优先使用布局指定值，wrap_content时占满父容器可用宽度
        val width = measureDimension(
            desiredSize = resources.displayMetrics.widthPixels,
            measureSpec = widthMeasureSpec
        )
        // 高度：优先使用布局指定值，wrap_content时使用进度条高度（加padding）
        val height = measureDimension(
            desiredSize = (progressHeight + paddingTop + paddingBottom).toInt(),
            measureSpec = heightMeasureSpec
        )
        // 设置最终尺寸
        setMeasuredDimension(width, height)
    }

    /**
     * 测量单个维度（宽度/高度）的工具方法
     */
    private fun measureDimension(desiredSize: Int, measureSpec: Int): Int {
        val mode = MeasureSpec.getMode(measureSpec)
        val size = MeasureSpec.getSize(measureSpec)
        return when (mode) {
            MeasureSpec.EXACTLY -> size // match_parent或固定值（如100dp）
            MeasureSpec.AT_MOST -> minOf(desiredSize, size) // wrap_content（不超过父容器）
            else -> desiredSize // 未指定（如ListView的item）
        }
    }

    /**
     * 核心绘制逻辑（背景+进度）
     */
    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        // 1. 计算可用区域（去除padding）
        val paddingLeft = paddingLeft.toFloat()
        val paddingRight = paddingRight.toFloat()
        val paddingTop = paddingTop.toFloat()
        val paddingBottom = paddingBottom.toFloat()
        val availableWidth = width.toFloat() - paddingLeft - paddingRight // 可用宽度（去除左右padding）
        val availableHeight = height.toFloat() - paddingTop - paddingBottom // 可用高度（去除上下padding）
        // 2. 计算背景矩形位置（垂直居中）
        val bgTop = paddingTop + (availableHeight - progressHeight) / 2f // 进度条顶部（垂直居中）
        val bgBottom = bgTop + progressHeight // 进度条底部
        bgRect.set(paddingLeft, bgTop, width.toFloat() - paddingRight, bgBottom)
        // 3. 计算进度矩形位置（宽度=当前进度比例×可用宽度）
        val progressRatio = currentProgress.toFloat() / maxProgress // 进度比例（0~1）
        val progressWidth = progressRatio * availableWidth // 进度条宽度（随进度变化）
        progressRect.set(
            paddingLeft,
            bgTop,
            paddingLeft + progressWidth, // 进度条右边界（随进度拉伸）
            bgBottom
        )
        // 4. 绘制背景（浅灰圆角矩形）
        canvas.drawRoundRect(bgRect, progressRadius, progressRadius, bgPaint)
        // 5. 绘制进度（橙色圆角矩形，进度>0时显示）
        if (currentProgress > 0) {
            canvas.drawRoundRect(progressRect, progressRadius, progressRadius, progressPaint)
        }
    }

    // ==================== 外部接口（核心功能） ====================
    /**
     * 设置当前进度（无动画）
     * @param progress 目标进度（自动截断到0~maxProgress）
     */
    fun setProgress(progress: Int) {
        val newProgress = progress.coerceIn(0, maxProgress) // 限制进度范围
        if (currentProgress != newProgress) {
            currentProgress = newProgress
            invalidate() // 重绘View（刷新进度）
        }
    }

    /**
     * 设置当前进度（带动画，更流畅）
     * @param progress 目标进度
     * @param duration 动画时长（默认300ms）
     */
    fun setProgressWithAnimation(progress: Int, duration: Long = 300) {
        val newProgress = progress.coerceIn(0, maxProgress)
        if (currentProgress == newProgress) return // 进度无变化，跳过动画
        // 用值动画渐变进度（从当前到目标）
        ValueAnimator.ofInt(currentProgress, newProgress).apply {
            this.duration = duration
            addUpdateListener { anim ->
                currentProgress = anim.animatedValue as Int
                invalidate() // 每帧重绘
            }
            start()
        }
    }

    /**
     * 设置最大进度（如100→200，需调整当前进度）
     */
    fun setMaxProgress(max: Int) {
        val newMax = max.coerceAtLeast(1) // 最大进度必须>0
        if (maxProgress != newMax) {
            maxProgress = newMax
            currentProgress = currentProgress.coerceIn(0, newMax) // 调整当前进度（避免超出新的最大值）
            invalidate()
        }
    }

    /**
     * 设置进度颜色（动态调整样式）
     */
    fun setProgressColor(color: Int) {
        if (progressColor != color) {
            progressColor = color
            progressPaint.color = color
            invalidate()
        }
    }
}